package main

import (
	"fmt"
	"sync"
)

func main() {
	/*
		第一次打印结果为 9->10 9->10 9->10 9->10 9->10 9->10 9->10 9->10 9->10 9->10 的原因：
		（1）for range 下的迭代变量 i 的值是共用的
		（2）main 函数所在的 goroutine 和后续启动的 goroutine 存在竞争关系

		*所以：在 for 循环下调用并发时要复制迭代变量后再使用，不要直接引用 for 迭代变量
	*/
	wg := sync.WaitGroup{}

	s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	//注：正确和错误写法不要同时执行
	//错误写法
	for i, v := range s {
		wg.Add(1)
		go func() {
			fmt.Print(i, "->", v, " ")
			wg.Done()
		}()
	} //9->10 9->10 9->10 9->10 9->10 9->10 9->10 9->10 9->10 9->10

	//正确写法
	for i, v := range s {
		wg.Add(1)

		//这里有一个实参到形参的值拷贝
		go func(i int, v int) {
			print(i, "->", v, " ")
			wg.Done()
		}(i, v)
	} //0->1 1->2 2->3 4->5 7->8 6->7 8->9 3->4 5->6 9->10

	wg.Wait()
}
